package cl.zeke.cursos.jsf2spring3jpa2.vista.security;

import cl.zeke.cursos.jsf2spring3jpa2.negocio.entities.Perfil;
import cl.zeke.cursos.jsf2spring3jpa2.negocio.entities.Usuario;
import cl.zeke.cursos.jsf2spring3jpa2.negocio.services.UsuarioService;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationManager implements AuthenticationManager {
    
    private static Logger log = LoggerFactory.getLogger(CustomAuthenticationManager.class);

    @Autowired
    private UsuarioService personaService;
    private Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder();

    @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {
        Usuario usuario;
        
        usuario = personaService.traerPorRut(auth.getName());
        if(usuario == null) {
            log.debug("Usuario no existe!");
            throw new BadCredentialsException("credenciales invalidas!");
        }
        
        if(usuario.getHabilitado() == false) {
            log.debug("Usuario no habilitado");
            throw new DisabledException("Usuario no habilitado");
        }

        if (passwordEncoder.isPasswordValid(usuario.getPassword(), (String) auth.getCredentials(), null) == false) {
            log.debug("Password incorrecto!");
            throw new BadCredentialsException("credenciales invalidas!");
        }

        return new UsernamePasswordAuthenticationToken(
                auth.getName(),
                auth.getCredentials(),
                getAuthorities(usuario));
    }

    private List<? extends GrantedAuthority> getAuthorities(Usuario usuario) {
        
        List<GrantedAuthority> rolesList = new ArrayList<GrantedAuthority>();

        if(usuario.getPerfil()  == null) {
            throw new DisabledException("credenciales invalidas!");
        }
        
        switch(usuario.getPerfil().getIdPerfil().intValue()) {
            case Perfil.ID_PERFIL_SUPER_ADMINISTRADOR:
                rolesList.add(new SimpleGrantedAuthority("PERFIL_SUPER_ADMINISTRADOR"));
                break;
            case Perfil.ID_PERFIL_ADMINISTRADOR:
                rolesList.add(new SimpleGrantedAuthority("PERFIL_ADMINISTRADOR"));
                break;
            case Perfil.ID_PERFIL_USUARIO:
                rolesList.add(new SimpleGrantedAuthority("PERFIL_USUARIO"));
                break;
            default:
                throw new DisabledException("credenciales invalidas!");
        }
        
        return rolesList;
    }
    
    
}
